package com.lzwork.gpt.utility.caller;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lzwork.utility.collection.CollUtility;
import com.lzwork.utility.collection.MapReader;
import com.lzwork.utility.pair.StringPair;
import com.lzwork.web.HttpRequester.ReturnData;

/**
 * Common caller for OpenAPI api standard.<br>
 * Base call API path is /v1/chat/completions
 * 
 * @author LiZheng
 * @date 2023年12月5日 下午5:39:29
 */

public class OpenApiCaller extends GptCaller
{
	static StringPair tokenHead(String token)
	{
		return new StringPair("Authorization", "Bearer " + token);
	}

	public static class OpenApiResult extends GptCallResult
	{
		@Override
		protected void afterCall(ReturnData responseData)
		{
			super.afterCall(responseData);

			JSONObject obj = getReturnData();

			JSONArray returns = obj.getJSONArray("choices");
			if (returns != null)
			{
				for (Object o : returns)
				{
					if (o instanceof Map)
					{
						Map<?, ?> item = MapReader.getSubMap((Map<?, ?>) o, "message", false);
						setResponse(MapReader.getMapStr(item, "content"));
						break;
					}
				}
			}
		}
	}

	public OpenApiCaller(String url, String token, String model)
	{
		super(url);

		header.add(tokenHead(token));
		this.model = model;
	}

	@Override
	protected CallResult createResult()
	{
		return new OpenApiResult();
	}

	protected List<StringPair> header = new ArrayList<>();
	protected String model;

	@Override
	public GptCallResult callChat(String chat, List<String> history, List<String> systemPrompt)
	{
		String path = url + "v1/chat/completions";

		JSONObject param = new JSONObject(true);

		param.put("model", model);

		List<JSONObject> msgList = new ArrayList<>();

		if (CollUtility.hasData(systemPrompt))
		{
			for (String str : systemPrompt)
			{
				msgList.add(makeMessage(Caller.System, str));
			}
		}
		msgList.add(makeMessage(Caller.User, chat));

		param.put("messages", msgList);

		return (GptCallResult) post(path, param, header);
	}
}
